"""
文件处理器模块
"""

import os
import logging
from typing import Optional, Dict, Any
from abc import ABC, abstractmethod
from django.core.files.uploadedfile import UploadedFile

logger = logging.getLogger(__name__)


class FileProcessor(ABC):
    """文件处理器基类"""

    @abstractmethod
    def can_process(self, file: UploadedFile) -> bool:
        """检查是否能处理该文件"""
        pass

    @abstractmethod
    def extract_text(self, file: UploadedFile) -> str:
        """提取文件中的文本内容"""
        pass

    @property
    @abstractmethod
    def supported_extensions(self) -> list:
        """支持的文件扩展名列表"""
        pass


class TxtFileProcessor(FileProcessor):
    """TXT文件处理器"""

    @property
    def supported_extensions(self) -> list:
        return [".txt"]

    def can_process(self, file: UploadedFile) -> bool:
        """检查是否为txt文件"""
        if not file or not file.name:
            return False

        file_ext = os.path.splitext(file.name.lower())[1]
        return file_ext in self.supported_extensions

    def extract_text(self, file: UploadedFile) -> str:
        """提取txt文件内容"""
        try:
            # 重置文件指针到开头
            file.seek(0)

            # 尝试不同的编码
            encodings = ["utf-8", "gbk", "gb2312", "latin-1"]
            content = None

            for encoding in encodings:
                try:
                    file.seek(0)  # 重置文件指针
                    content = file.read().decode(encoding)
                    break
                except UnicodeDecodeError:
                    continue

            if content is None:
                # 如果所有编码都失败，使用错误替换模式
                file.seek(0)
                content = file.read().decode("utf-8", errors="replace")

            return content.strip()

        except Exception as e:
            logger.error(f"提取txt文件内容失败: {e}")
            return f"文件读取失败: {str(e)}"


class MarkdownFileProcessor(FileProcessor):
    """Markdown文件处理器"""

    @property
    def supported_extensions(self) -> list:
        return [".md", ".markdown"]

    def can_process(self, file: UploadedFile) -> bool:
        """检查是否为markdown文件"""
        if not file or not file.name:
            return False

        file_ext = os.path.splitext(file.name.lower())[1]
        return file_ext in self.supported_extensions

    def extract_text(self, file: UploadedFile) -> str:
        """提取markdown文件内容"""
        try:
            # 重置文件指针到开头
            file.seek(0)

            # 尝试不同的编码
            encodings = ["utf-8", "gbk", "gb2312", "latin-1"]
            content = None

            for encoding in encodings:
                try:
                    file.seek(0)  # 重置文件指针
                    content = file.read().decode(encoding)
                    break
                except UnicodeDecodeError:
                    continue

            if content is None:
                # 如果所有编码都失败，使用错误替换模式
                file.seek(0)
                content = file.read().decode("utf-8", errors="replace")

            return content.strip()

        except Exception as e:
            logger.error(f"提取markdown文件内容失败: {e}")
            return f"文件读取失败: {str(e)}"


# Word文档处理器 python-docx库
"""
class DocxFileProcessor(FileProcessor):
    '''Word文档处理器'''
    
    @property
    def supported_extensions(self) -> list:
        return ['.docx']
    
    def can_process(self, file: UploadedFile) -> bool:
        '''检查是否为Word文档'''
        if not file or not file.name:
            return False
        
        file_ext = os.path.splitext(file.name.lower())[1]
        return file_ext in self.supported_extensions
    
    def extract_text(self, file: UploadedFile) -> str:
        '''提取Word文档内容'''
        try:
            from docx import Document
            import io
            
            # 重置文件指针到开头
            file.seek(0)
            
            # 读取文件内容到内存
            file_content = file.read()
            
            # 使用io.BytesIO创建文件对象
            doc_file = io.BytesIO(file_content)
            
            # 解析Word文档
            doc = Document(doc_file)
            
            # 提取所有段落文本
            paragraphs = []
            for paragraph in doc.paragraphs:
                if paragraph.text.strip():
                    paragraphs.append(paragraph.text.strip())
            
            return '\n'.join(paragraphs)
            
        except ImportError:
            return "需要安装python-docx库来支持Word文档: pip install python-docx"
        except Exception as e:
            logger.error(f"提取Word文档内容失败: {e}")
            return f"Word文档处理失败: {str(e)}"
"""


# PDF文档处理器 PyPDF2或pdfplumber库）
"""
class PdfFileProcessor(FileProcessor):
    '''PDF文档处理器'''
    
    @property
    def supported_extensions(self) -> list:
        return ['.pdf']
    
    def can_process(self, file: UploadedFile) -> bool:
        '''检查是否为PDF文档'''
        if not file or not file.name:
            return False
        
        file_ext = os.path.splitext(file.name.lower())[1]
        return file_ext in self.supported_extensions
    
    def extract_text(self, file: UploadedFile) -> str:
        '''提取PDF文档内容'''
        try:
            import pdfplumber
            
            # 重置文件指针到开头
            file.seek(0)
            
            # 读取文件内容到内存
            file_content = file.read()
            
            # 使用pdfplumber提取文本
            with pdfplumber.open(io.BytesIO(file_content)) as pdf:
                text = ""
                for page in pdf.pages:
                    page_text = page.extract_text()
                    if page_text:
                        text += page_text + "\n"
                
                return text.strip()
            
        except ImportError:
            return "需要安装pdfplumber库来支持PDF文档: pip install pdfplumber"
        except Exception as e:
            logger.error(f"提取PDF文档内容失败: {e}")
            return f"PDF文档处理失败: {str(e)}"
"""


class FileProcessorManager:
    """文件处理器管理器"""

    def __init__(self):
        self.processors = [
            TxtFileProcessor(),
            MarkdownFileProcessor(),
            # 未来可以添加更多处理器
            # DocFileProcessor(),
            # DocxFileProcessor(),
            # PdfFileProcessor(),
        ]

    def get_processor(self, file: UploadedFile) -> Optional[FileProcessor]:
        """获取适合的文件处理器"""
        for processor in self.processors:
            if processor.can_process(file):
                return processor
        return None

    def extract_text_from_upload(self, file: UploadedFile) -> str:
        """从上传的文件中提取文本"""
        if not file:
            return ""

        processor = self.get_processor(file)
        if not processor:
            return f"不支持的文件类型: {file.name}"

        try:
            content = processor.extract_text(file)
            if not content:
                return "文件内容为空"

            # 限制文件内容长度，避免提示词过长
            max_length = 10000  # 10KB限制
            if len(content) > max_length:
                content = (
                    content[:max_length] + "\n\n[文件内容已截断，仅显示前10000个字符]"
                )

            return content

        except Exception as e:
            logger.error(f"文件处理失败: {e}")
            return f"文件处理失败: {str(e)}"

    def get_supported_extensions(self) -> list:
        """获取所有支持的文件扩展名"""
        extensions = []
        for processor in self.processors:
            extensions.extend(processor.supported_extensions)
        return extensions


# 全局文件处理器管理器实例
file_processor_manager = FileProcessorManager()


def extract_text_from_upload(file: UploadedFile) -> str:
    """
    从上传的文件中提取文本内容
    """
    return file_processor_manager.extract_text_from_upload(file)
